package com.itheima.ydd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.ydd.common.ResultData;
import com.itheima.ydd.dto.SysMenuDto;
import com.itheima.ydd.dto.SysRoleDto;
import com.itheima.ydd.entity.SysMenu;
import com.itheima.ydd.entity.SysRole;
import com.itheima.ydd.entity.SysRoleMenu;
import com.itheima.ydd.mapper.SysRoleMapper;
import com.itheima.ydd.service.ISysMenuService;
import com.itheima.ydd.service.ISysRoleMenuService;
import com.itheima.ydd.service.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author author
 * @since 2022-05-22
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
    @Autowired
    private ISysRoleMenuService sysRoleMenuService;
    @Autowired
    private ISysMenuService sysMenuService;

    /**
     * 角色列表-全部
     * @return
     */
    @Override
    public ResultData getAllData() {
        //执行查询
        List<SysRole> list = list();
        return ResultData.ok("查询成功！", list);
    }

    /**
     * 角色列表-分页
     * @param page
     * @param limit
     * @param name
     * @return
     */
    @Override
    public ResultData page(Integer page, Integer limit, String name) {
        //分页构造器
        Page pageInfo = new Page(page, limit);

        //模糊查询条件
        LambdaQueryWrapper<SysRole> lqw = new LambdaQueryWrapper<>();
        lqw.like(name != null, SysRole::getName, name);

        //排序

        //分页查询
        page(pageInfo, lqw);
        //封装对象
        HashMap<String, Object> map = new HashMap<>();
        map.put("data", pageInfo.getRecords());
        map.put("count", pageInfo.getTotal());
        map.put("totalPages", pageInfo.getSize());
        map.put("pageSize", limit);
        map.put("currentPage", pageInfo.getCurrent());
        //返回
        return ResultData.ok("查询成功", map);
    }

    /**
     * 角色详情（回显）
     * @param id
     * @return
     */
    @Override
    public ResultData rowInfo(String id) {
        //根据id获取角色信息
        SysRole byId = getById(id);
        //新建一个dto对象
        SysRoleDto sysRoleDto = new SysRoleDto();
        //拷贝数据
        BeanUtils.copyProperties(byId, sysRoleDto);
        //查询权限
      /*   ResultData resultData = sysMenuService.allData();
       List<SysMenuDto> data = ( List<SysMenuDto>) resultData.getData();*/
        //查询构造器
        LambdaQueryWrapper<SysRoleMenu> lqw = new LambdaQueryWrapper<>();
        //添加查询条件（当前角色所有权限）
        lqw.eq(SysRoleMenu::getRoleId, byId.getId());
        //新建dto集合用于封装权限
        List<SysMenuDto> sysMenuDtos = new ArrayList<>();
        //执行查询（查询结果为当前用户所拥有的权限）
        List<SysRoleMenu> list = sysRoleMenuService.list(lqw);
        //所以权限id集合
        List<String> menuIds = new ArrayList<>();
        list.forEach(sysRoleMenu -> {
            String menuId = sysRoleMenu.getMenuId();
            menuIds.add(menuId);
        });
        LambdaQueryWrapper<SysMenu> lqw1 = new LambdaQueryWrapper<>();
        lqw1.in(SysMenu::getId,menuIds);
        //所有菜单
        List<SysMenu> allSysMenuList = sysMenuService.list(lqw1);
        //pid为0，父菜单查询条件
        lqw1.eq(SysMenu::getPid,0);
        //父菜单
        List<SysMenu> sysMenuList = sysMenuService.list(lqw1);
        for (SysMenu sysMenu : sysMenuList) {
            //父菜单id
            Integer id1 = sysMenu.getId();
            //调用递归方法封装菜单
            List<SysMenuDto> list1 = getChild(id1,allSysMenuList);
            //新建dto对象
            SysMenuDto sysMenuDto = new SysMenuDto();
            //拷贝父级菜单
            BeanUtils.copyProperties(sysMenu,sysMenuDto);
            //将递归封装的菜单添加为父菜单的子菜单
            sysMenuDto.setChildren(list1);
            //将父菜单添加进父菜单集合
            sysMenuDtos.add(sysMenuDto);
        }
        //设置当前对象权限集合
        sysRoleDto.setAuthList(sysMenuDtos);

        return ResultData.ok("", sysRoleDto);
    }

    /**
     * 角色删除
     * @param id
     * @return
     */
    @Override
    @Transactional
    public ResultData del(String id) {
        //根据id获取当前角色信息
        SysRole role = getById(id);
        //构建查询构造器
        LambdaQueryWrapper<SysRoleMenu> qw = new LambdaQueryWrapper<>();
        //添加查询条件
        qw.eq(SysRoleMenu::getRoleId, role.getId());
        //删除当前角色关联所有权限信息
        sysRoleMenuService.remove(qw);
        //删除角色
        removeById(id);
        return ResultData.ok("删除成功",null);
    }

    /**
     * 角色修改
     * @param sysRoleDto
     * @return
     */
    @Override
    public ResultData update(SysRoleDto sysRoleDto) {
        //新建一个role对象拷贝dto内角色信息
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDto, sysRole);
        //修改角色表对应信息
        updateById(sysRole);
        //获取id
        String roleId = sysRoleDto.getId();
        //获取前端传来的菜单id集合
        List<String> menuids = sysRoleDto.getMenuids();
        //构建查询构造器
        LambdaQueryWrapper<SysRoleMenu> qw = new LambdaQueryWrapper<>();
        //添加查询条件
        qw.eq(SysRoleMenu::getRoleId, roleId);
        //删除原来关联的权限信息
        sysRoleMenuService.remove(qw);
        //重新添加权限信息
        for (String menuid : menuids) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuid);
            sysRoleMenuService.save(sysRoleMenu);
        }
        return ResultData.ok("修改成功",null);
    }

    /**
     * 角色添加
     * @param sysRoleDto
     * @return
     */
    @Override
    @Transactional
    public ResultData add(SysRoleDto sysRoleDto) {
        //设置创建时间和修改时间
        sysRoleDto.setCreateDate(LocalDateTime.now());
        sysRoleDto.setUpdateDate(LocalDateTime.now());
        //存储进角色表
        save(sysRoleDto);
        //获取添加数据的id
        String id = sysRoleDto.getId();
        //获取所有菜单信息
        List<String> menuids = sysRoleDto.getMenuids();
        //遍历挨个存入菜单表
        for (String menuid : menuids) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(id);
            sysRoleMenu.setMenuId(menuid);
            sysRoleMenuService.save(sysRoleMenu);
        }
        return ResultData.ok("添加成功",null);

    }
    /**
     * 递归封装菜单集合
     * @param id1
     * @param allSysMenuList
     * @return
     */
    private List<SysMenuDto> getChild(Integer id1, List<SysMenu> allSysMenuList) {
        //创建一个dto集合用于封装菜单
        List<SysMenuDto> childList = new ArrayList<>();
        //遍历当前用户所拥有的所有权限
        for (SysMenu sysMenu : allSysMenuList) {
            //判断当前权限父id是否与传入父菜单id相同
            if (sysMenu.getPid().equals(id1)){
                //相同则创建dto对象拷贝
                SysMenuDto sysMenuDto = new SysMenuDto();
                BeanUtils.copyProperties(sysMenu,sysMenuDto);
                //添加进集合
                childList.add(sysMenuDto);
            }
        }
        for (SysMenuDto sysMenuDto : childList) {
            //遍历子菜单，再次调用方法本身进行递归
            List<SysMenuDto> child = getChild(sysMenuDto.getId(), allSysMenuList);
            sysMenuDto.setChildren(child);
        }
        //出递归条件
        if (childList.size() == 0){
            return null;
        }
        return childList;

    }







}
